home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / gfx / 3d / irit50src.lha / irit5 / grapdrvs / djggraph.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-21  |  42.2 KB  |  997 lines

  1. /*****************************************************************************
  2. *   "Irit" - the 3d polygonal solid modeller.                     *
  3. *                                         *
  4. * Written by:  Gershon Elber                       Ver 0.1, Mar. 1990    *
  5. ******************************************************************************
  6. * MSDOS graphical interface for IRIT. Based on intr_lib windowing library.   *
  7. *****************************************************************************/
  8.  
  9. #include <time.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include <conio.h>
  14. #include "djggraph.h"
  15.  
  16. #define DJG_MAP_X_COORD(x) ((int) ((x + 1.0) * ViewWidth2))
  17. #define DJG_MAP_Y_COORD(y) ((int) ((1.0 - y) * ViewHeight2))
  18.  
  19. int IGGlblInputWindowID = -1,
  20.     IGGlblViewWindowID = -1,
  21.     IGGlblTransWindowID = -1;
  22.  
  23. static int
  24.     ViewWidth2 = 100,
  25.     ViewHeight2 = 100,
  26.     GlblWindowFrameWidth = 8,                   /* Window color configuration. */
  27.     GlblViewFrameColor = RED,
  28.     GlblViewBackColor = BLUE,
  29.     GlblTransFrameColor = RED,
  30.     GlblTransBackColor = BLUE,
  31.     GlblInputFrameColor = RED,
  32.     GlblInputBackColor = BLUE,
  33.     GlblDrawHeader = FALSE,      /* Window general attributes configuration. */
  34.     GlblSmoothTextScroll = TRUE,
  35.     GlblIntrSaveMethod = INTR_SAVE_CONV,
  36.     GlblMouseSensitivity = 10,
  37.     GlblJoystickExists = FALSE,
  38.     GlblMouseExists = TRUE;
  39. static char
  40.     *GlblViewWndwPos = "0.03, 0.03, 0.67, 0.67",     /* Location of windows. */
  41.     *GlblViewWndwPosNoInput = "0.03, 0.03, 0.67, 0.97",
  42.     *GlblTransWndwPos = "0.73, 0.03, 0.97, 0.67",
  43.     *GlblTransWndwPosNoInput = "0.73, 0.03, 0.97, 0.97",
  44.     *GlblInputWndwPos = "0.03, 0.73, 0.97, 0.97",
  45.     *GlblIntrSaveDisk = ".";
  46.  
  47. #ifdef DJGCC
  48. #define NUM_OF_TEXT_LINES 200
  49. #else
  50. #define NUM_OF_TEXT_LINES 50
  51. #endif /* DJGCC */
  52.  
  53. /* Interactive menu setup structure: */
  54. #define INTERACT_NUM_OF_STRINGS        3
  55. #define INTERACT_NUM_OF_SUB_WNDWS    15
  56. #define INTERACT_SUB_WINDOW_HEIGHT    0.035 /* Actually half Height/Width. */
  57. #define INTERACT_SUB_WINDOW_WIDTH    0.8
  58. #define INTERACT_X_CENTER        ((SW_MAX_X + SW_MIN_X) / 2.0 + 0.02)
  59.  
  60. typedef struct InteractString {
  61.     IntrRType X, Y;
  62.     int Color;
  63.     char *Str;
  64. } InteractString;
  65.  
  66. typedef struct InteractSubWindow {
  67.     IntrRType X, Y;                       /* Center points. */
  68.     IGGraphicEventType InteractCode;
  69.     int Color,
  70.     TextInside; /* If TRUE, Str will be in window, otherwise left to it. */
  71.     char *Str;
  72. } InteractSubWindow;
  73.  
  74. typedef struct InteractWindowStruct {     /* The interactive menu structures. */
  75.     /* Rotate, Translate, Scale strings: */
  76.     InteractString Strings[INTERACT_NUM_OF_STRINGS];
  77.     InteractSubWindow SubWindows[INTERACT_NUM_OF_SUB_WNDWS];
  78. } InteractWindowStruct;
  79.  
  80. static IntrBType
  81.     HasInputWindow = FALSE;
  82.  
  83. static int
  84.     InteractNumOfSubWndws = INTERACT_NUM_OF_SUB_WNDWS;
  85.     
  86. /* Interactive mode menu set up structure is define below: */
  87. static InteractWindowStruct InteractMenu = {
  88.     { { 0.0, -0.63, RED,   "Rotate" },
  89.       { 0.0, -0.34, GREEN, "Translate" },
  90.       { 0.0, -0.05, CYAN,  "Scale" },
  91.     },
  92.     { { 0.0, -0.9,  IG_EVENT_SCR_OBJ_TGL,    CYAN,   TRUE,  "Screen Coords." },
  93.       { 0.0, -0.79, IG_EVENT_PERS_ORTHO_TGL, BLUE,   TRUE,  "Perspectiv" },
  94.       { 0.0, -0.72, IG_EVENT_PERS_ORTHO_Z,   BLUE,   FALSE, "Z" },
  95.       { 0.0, -0.57, IG_EVENT_ROTATE_X,       RED,    FALSE, "X" }, /* Rot */
  96.       { 0.0, -0.50, IG_EVENT_ROTATE_Y,       RED,    FALSE, "Y" },
  97.       { 0.0, -0.43, IG_EVENT_ROTATE_Z,       RED,    FALSE, "Z" },
  98.       { 0.0, -0.28, IG_EVENT_TRANSLATE_X,    GREEN,  FALSE, "X" }, /* Trans */
  99.       { 0.0, -0.21, IG_EVENT_TRANSLATE_Y,    GREEN,  FALSE, "Y" },
  100.       { 0.0, -0.14, IG_EVENT_TRANSLATE_Z,    GREEN,  FALSE, "Z" },
  101.       { 0.0,  0.01, IG_EVENT_SCALE,          CYAN,   FALSE, "" },  /* Scale */
  102.       { 0.0,  0.12, IG_EVENT_DEPTH_CUE,      MAGENTA,TRUE,  "Depth cue" },
  103.       { 0.0,  0.3,  IG_EVENT_SAVE_MATRIX,    YELLOW, TRUE,  "Save Matrix" },
  104.       { 0.0,  0.39, IG_EVENT_PUSH_MATRIX,    YELLOW, TRUE,  "Push Matrix" },
  105.       { 0.0,  0.48, IG_EVENT_POP_MATRIX,     YELLOW, TRUE,  "Pop Matrix" },
  106.       { 0.0,  0.62, IG_EVENT_QUIT,           WHITE,  TRUE,  "Quit" },
  107.     }
  108. };
  109.     
  110. static IntrPopUpMenuStruct *PUWndwMenu;
  111. static char *PopUpMenuStrs[] = {
  112.     "Redraw All",
  113.     "Move",
  114.     "Resize",
  115.     "Pop",
  116.     "Push",
  117.     "Zoom",
  118.     "Reset",
  119.     "Headers",
  120. };
  121. #define POP_UP_MENU_SIZE (sizeof(PopUpMenuStrs) / sizeof(char *))
  122.  
  123. static void SetColorIndex(int color);
  124. static void SetViewWindowFBBox(int WindowID);
  125. static IntrEventType LclGetChar(int *x, int *y);
  126. static void SetBBoxSize(IntrBBoxStruct *BBox, char *GlblTextWindowPos);
  127. static void ViewWndwRefreshFunction(int WindowID);
  128. static void TransWndwRefreshFunction(int WindowID);
  129. static void TransWndwRefreshFunctionAux(void);
  130. static void InteractUpdateMenu(char *Str, int Entry);
  131. static void InputWndwRefreshFunction(int WindowID);
  132. static void SetMaximumBBoxSize(int WindowID);
  133. static void PopUpMenuFunc(int KeyStroke);
  134.  
  135. /*****************************************************************************
  136. * DESCRIPTION:                                                               M
  137. * Optionally construct a state pop up menu for the driver, if has one.       M
  138. *                                                                            *
  139. * PARAMETERS:                                                                M
  140. *   None                                                                     *
  141. *                                                                            *
  142. * RETURN VALUE:                                                              M
  143. *   void                                                                     M
  144. *                                                                            *
  145. * KEYWORDS:                                                                  M
  146. *   IGCreateStateMenu                                                        M
  147. *****************************************************************************/
  148. void IGCreateStateMenu(void)
  149. {
  150. }
  151.  
  152. /*****************************************************************************
  153. * DESCRIPTION:                                                               M
  154. * Handles the events of the pop up window.                                   M
  155. *                                                                            *
  156. * PARAMETERS:                                                                M
  157. *   State:      Event to handle.                                             M
  158. *   Refresh:    Do we need to refresh the screen according to what we know   M
  159. *        on entry.                             M
  160. *                                                                            *
  161. * RETURN VALUE:                                                              M
  162. *   int:        TRUE, if we need to refresh the screen.                      M
  163. *                                                                            *
  164. * KEYWORDS:                                                                  M
  165. *   IGHandleState                                                            M
  166. *****************************************************************************/
  167. int IGHandleState(int State, int Refresh)
  168. {
  169.     int UpdateView = TRUE;
  170.  
  171.     switch (State) {
  172.     case IG_STATE_DEPTH_CUE:
  173.         IGGlblDepthCue = !IGGlblDepthCue;
  174.         break;
  175.     case IG_STATE_DOUBLE_BUFFER:
  176.         IGGlblDoDoubleBuffer = !IGGlblDoDoubleBuffer;
  177.         break;
  178.     case IG_STATE_WIDER_LINES:
  179.         IGGlblLineWidth *= 2;
  180.         break;
  181.     case IG_STATE_NARROW_LINES:
  182.         IGGlblLineWidth /= 2;
  183.         break;
  184.     default:
  185.         UpdateView = IGDefaultStateHandler(State, Refresh);
  186.         break;
  187.     }
  188.  
  189.     if (UpdateView)
  190.     IntrWndwRedrawAll();
  191.  
  192.     IGCreateStateMenu();
  193.  
  194.     return UpdateView;
  195. }
  196.  
  197. /*****************************************************************************
  198. * DESCRIPTION:                                                               M
  199. * Make some sound.                                                           M
  200. *                                                                            *
  201. * PARAMETERS:                                                                M
  202. *   None                                                                     M
  203. *                                                                            *
  204. * RETURN VALUE:                                                              M
  205. *   void                                                                     M
  206. *                                                                            *
  207. * KEYWORDS:                                                                  M
  208. *   IGIritBeep                                                               M
  209. *****************************************************************************/
  210. void IGIritBeep(void)
  211. {
  212. }
  213.  
  214. /*****************************************************************************
  215. * DESCRIPTION:                                                               M
  216. * Low level 2D drawing routine. Coordinates are normalized to -1 to 1 by     M
  217. * this time.                                                                 M
  218. *                                                                            *
  219. * PARAMETERS:                                                                M
  220. *   X, Y:    Coordinates of 2D location to move to.                          M
  221. *                                                                            *
  222. * RETURN VALUE:                                                              M
  223. *   void                                                                     M
  224. *                                                                            *
  225. * KEYWORDS:                                                                  M
  226. *   IGMoveTo2D                                                               M
  227. *****************************************************************************/
  228. void IGMoveTo2D(RealType X, RealType Y)
  229. {
  230.     GRSMoveTo(DJG_MAP_X_COORD(X), DJG_MAP_Y_COORD(Y));
  231. }
  232.  
  233. /*****************************************************************************
  234. * DESCRIPTION:                                                               M
  235. * Low level 2D drawing routine. Coordinates are normalized to -1 to 1 by     M
  236. * this time.                                                                 M
  237. *                                                                            *
  238. * PARAMETERS:                                                                M
  239. *   X, Y:    Coordinates of 2D location to draw to.                          M
  240. *                                                                            *
  241. * RETURN VALUE:                                                              M
  242. *   void                                                                     M
  243. *                                                                            *
  244. * KEYWORDS:                                                                  M
  245. *   IGLineTo2D                                                               M
  246. *****************************************************************************/
  247. void IGLineTo2D(RealType X, RealType Y)
  248. {
  249.     GRSLineTo(DJG_MAP_X_COORD(X), DJG_MAP_Y_COORD(Y));
  250. }
  251.  
  252. /*****************************************************************************
  253. * DESCRIPTION:                                                               M
  254. * Sets the intensity of a color (high or low).                     M
  255. *                                                                            *
  256. * PARAMETERS:                                                                M
  257. *   High:     TRUE for high, FALSE for low.                                  M
  258. *                                                                            *
  259. * RETURN VALUE:                                                              M
  260. *   void                                                                     M
  261. *                                                                            *
  262. * KEYWORDS:                                                                  M
  263. *   IGSetColorIntensity                                                      M
  264. *****************************************************************************/
  265. void IGSetColorIntensity(int High)
  266. {
  267. }
  268.  
  269. /*****************************************************************************
  270. * DESCRIPTION:                                                               M
  271. * Sets the color of an object according to its color/rgb attributes.         M
  272. *   If object has an RGB attribute it will be used. Otherwise, if the object M
  273. * has a COLOR attribute it will use. Otherwise, WHITE will be used.         M
  274. *                                                                            *
  275. * PARAMETERS:                                                                M
  276. *   PObj:      To set the drawing color to its color.                        M
  277. *                                                                            *
  278. * RETURN VALUE:                                                              M
  279. *   void                                                                     M
  280. *                                                                            *
  281. * KEYWORDS:                                                                  M
  282. *   IGSetColorObj                                                            M
  283. *****************************************************************************/
  284. void IGSetColorObj(IPObjectStruct *PObj)
  285. {
  286.     int c, Color[3];
  287.  
  288.     if (AttrGetObjectRGBColor(PObj, &Color[0], &Color[1], &Color[2])) {
  289.     SetColorIndex((Color[0] + Color[1] + Color[2]) % 15 + 1);
  290.     }
  291.     else if ((c = AttrGetObjectColor(PObj)) != IP_ATTR_NO_COLOR) {
  292.     SetColorIndex(c);
  293.     }
  294.     else {
  295.     /* Use white as default color: */
  296.     GRSetColor(WHITE);
  297.     }
  298. }
  299.  
  300. /*****************************************************************************
  301. * DESCRIPTION:                                                               M
  302. * Sets the line width to draw the given object, in pixels.             M
  303. *                                                                            *
  304. * PARAMETERS:                                                                M
  305. *   Width:    In pixels of lines to draw with.                               M
  306. *                                                                            *
  307. * RETURN VALUE:                                                              M
  308. *   void                                                                     M
  309. *                                                                            *
  310. * KEYWORDS:                                                                  M
  311. *   IGSetWidthObj                                                            M
  312. *****************************************************************************/
  313. void IGSetWidthObj(int Width)
  314. {
  315. }
  316.  
  317. /*****************************************************************************
  318. * DESCRIPTION:                                                               *
  319. * Sets the color according to the given color index.                     *
  320. *                                                                            *
  321. * PARAMETERS:                                                                *
  322. *   color:     Index of color to use. Must be between 0 and IG_MAX_COLOR.    *
  323. *                                                                            *
  324. * RETURN VALUE:                                                              *
  325. *   void                                                                     *
  326. *****************************************************************************/
  327. static void SetColorIndex(int color)
  328. {
  329.     if (color >= MAX_COLOR)
  330.     color = WHITE;
  331.  
  332.     GRSetColor(color);
  333. }
  334.  
  335. /*****************************************************************************
  336. * DESCRIPTION:                                                               M
  337. * Initializes  the Intr_lib library.                         M
  338. *                                                                            *
  339. * PARAMETERS:                                                                M
  340. *   None                                                                     M
  341. *                                                                            *
  342. * RETURN VALUE:                                                              M
  343. *   void                                                                     M
  344. *                                                                            *
  345. * KEYWORDS:                                                                  M
  346. *   InitIntrLibWindows                                                       M
  347. *****************************************************************************/
  348. void InitIntrLibWindows(void)
  349. {
  350.     IntrCursorShapeStruct Cursor;
  351.     IntrBBoxStruct BBox;
  352.     IntrFBBoxStruct FBBox;
  353.  
  354.     IntrSetSaveBackPath(GlblIntrSaveDisk);
  355.     IntrSetSaveBackMethod(GlblIntrSaveMethod);
  356.     IntrSetHandleInternalEvents(TRUE, FALSE);
  357.  
  358.     IntrInit();
  359.  
  360.     IntrSetMouseSensitivity(GlblMouseSensitivity);
  361.     IntrSetInputDevice((GlblMouseExists ? INTR_INPT_DEVICE_MOUSE : 0) |
  362.                (GlblJoystickExists ? INTR_INPT_DEVICE_JOYSTICK : 0) |
  363.                INTR_INPT_DEVICE_KEYBOARD);
  364.  
  365.     IntrRegisterKeyStroke(0x13B /* F1 */, PopUpMenuFunc);
  366.  
  367.     /* Set the default cursor to arrow. */
  368.     Cursor.CursorType = INTR_CURSOR_ARROW;
  369.     IntrSetCursorType(&Cursor);
  370.  
  371.     /* Prepare the pop up menu. */
  372.     PUWndwMenu = IntrPopUpMenuCreate("Windows", PopUpMenuStrs, 0,
  373.                   POP_UP_MENU_SIZE,
  374.                   INTR_COLOR_GREEN, INTR_COLOR_CYAN,
  375.                   INTR_COLOR_YELLOW, INTR_COLOR_MAGENTA,
  376.                                   16, &Cursor);
  377.  
  378.  
  379.     if (HasInputWindow)
  380.         SetBBoxSize(&BBox, GlblViewWndwPos);
  381.     else
  382.     SetBBoxSize(&BBox, GlblViewWndwPosNoInput);
  383.     IGGlblViewWindowID = IntrWndwCreate("View",
  384.                     GlblWindowFrameWidth,
  385.                     &BBox,
  386.                     GlblViewFrameColor,
  387.                     GlblViewBackColor,
  388.                     &Cursor,
  389.                     NULL,
  390.                     ViewWndwRefreshFunction);
  391.     IntrWndwSetDrawHeader(IGGlblViewWindowID, GlblDrawHeader);
  392.     IntrWndwPop(IGGlblViewWindowID, TRUE, FALSE);
  393.     SetViewWindowFBBox(IGGlblViewWindowID);
  394.     
  395.     if (HasInputWindow)
  396.         SetBBoxSize(&BBox, GlblTransWndwPos);
  397.     else
  398.     SetBBoxSize(&BBox, GlblTransWndwPosNoInput);
  399.  
  400.     IGGlblTransWindowID = IntrWndwCreate("Transformations",
  401.                      GlblWindowFrameWidth,
  402.                      &BBox,
  403.                      GlblTransFrameColor,
  404.                      GlblTransBackColor,
  405.                      &Cursor,
  406.                      NULL,
  407.                      TransWndwRefreshFunction);
  408.     FBBox.FXmin = FBBox.FYmin = -1.0;
  409.     FBBox.FXmax = 1.0;
  410.     FBBox.FYmax = 0.7;
  411.     IntrWndwSetFBBox(IGGlblTransWindowID, &FBBox);
  412.     IntrWndwSetDrawHeader(IGGlblTransWindowID, GlblDrawHeader);
  413.     IntrWndwPop(IGGlblTransWindowID, TRUE, TRUE);
  414.  
  415.     if (HasInputWindow) {
  416.     SetBBoxSize(&BBox, GlblInputWndwPos);
  417.     IGGlblInputWindowID = IntrWndwCreate("Input",
  418.                          GlblWindowFrameWidth,
  419.                          &BBox,
  420.                          GlblInputFrameColor,
  421.                          GlblInputBackColor,
  422.                          &Cursor,
  423.                          NULL,
  424.                          InputWndwRefreshFunction);
  425.     IntrTextInitWindow(IGGlblInputWindowID, TRUE, INTR_COLOR_YELLOW,
  426.                INTR_COLOR_RED, INTR_SCRLBAR_NONE,
  427.                INTR_SCRLBAR_LEFT, NUM_OF_TEXT_LINES, 90);
  428.     IntrWndwSetDrawHeader(IGGlblInputWindowID, GlblDrawHeader);
  429.     IntrTextSetSmoothScroll(GlblSmoothTextScroll);
  430.     IntrWndwPop(IGGlblInputWindowID, TRUE, TRUE);
  431.     }
  432.  
  433.     /* Make the get line intr_lib routine use this routine to get chars. */
  434.     GRSetGetKeyFunc(LclGetChar);
  435. }
  436.  
  437. /*****************************************************************************
  438. * DESCRIPTION:                                                               M
  439. * Terminates the Intr_lib library.                                           M
  440. *                                                                            *
  441. * PARAMETERS:                                                                M
  442. *   None                                                                     *
  443. *                                                                            *
  444. * RETURN VALUE:                                                              M
  445. *   void                                                                     M
  446. *                                                                            *
  447. * KEYWORDS:                                                                  M
  448. *   CloseIntrLibWindows                                                      M
  449. *****************************************************************************/
  450. void CloseIntrLibWindows(void)
  451. {
  452.     IntrPopUpMenuDelete(PUWndwMenu);
  453.     IntrWndwDelete(IGGlblViewWindowID, FALSE);
  454.     IntrWndwDelete(IGGlblTransWindowID, FALSE);
  455.     if (HasInputWindow)
  456.     IntrWndwDelete(IGGlblInputWindowID, FALSE);
  457.  
  458.     IntrClose();
  459. }
  460.  
  461. /*****************************************************************************
  462. * DESCRIPTION:                                                               *
  463. * Handles input events                                                       *
  464. *                                                                            *
  465. * PARAMETERS:                                                                *
  466. *   ChangeFactor:        A continuous numeric value between -1 and 1. This   *
  467. *             value will be used to set amount of event such as   *
  468. *             rotation or translation.                 *
  469. *                                                                            *
  470. * RETURN VALUE:                                                              *
  471. *   IGGraphicEventType:  Type of new event.                                  *
  472. *****************************************************************************/
  473. IGGraphicEventType GetGraphicEvent(RealType *ChangeFactor)
  474. {
  475.     int i, x, y;
  476.     IGGraphicEventType InteractCode;
  477.  
  478.     while (TRUE) {
  479.     IntrRType Wx, Wy;
  480.  
  481.     switch (IntrGetEventWait(&x, &y)) {
  482.         case INTR_EVNT_SELECT:
  483.         if (IntrMapEventToRWindow(IGGlblTransWindowID, x, y, &Wx, &Wy)) {
  484.             if (Wx < -INTERACT_SUB_WINDOW_WIDTH ||
  485.             Wx > INTERACT_SUB_WINDOW_WIDTH)
  486.             break;
  487.             for (i = 0; i < InteractNumOfSubWndws; i++)
  488.             if (Wy < InteractMenu.SubWindows[i].Y +
  489.                         INTERACT_SUB_WINDOW_HEIGHT &&
  490.                 Wy > InteractMenu.SubWindows[i].Y -
  491.                         INTERACT_SUB_WINDOW_HEIGHT) {
  492.                 InteractCode = InteractMenu.SubWindows[i].InteractCode;
  493.  
  494.                 switch (InteractCode) {
  495.                 case IG_EVENT_SCR_OBJ_TGL:
  496.                     switch (IGGlblTransformMode) {
  497.                     case IG_TRANS_SCREEN:
  498.                         InteractUpdateMenu("Object Coords.", 0);
  499.                         IGGlblTransformMode = IG_TRANS_OBJECT;
  500.                         break;
  501.                     case IG_TRANS_OBJECT:
  502.                         InteractUpdateMenu("Screen Coords.", 0);
  503.                         IGGlblTransformMode = IG_TRANS_SCREEN;
  504.                         break;
  505.                     }
  506.                     break;
  507.                 case IG_EVENT_PERS_ORTHO_TGL:
  508.                     switch (IGGlblViewMode) {
  509.                     case IG_VIEW_PERSPECTIVE:
  510.                         InteractUpdateMenu("Orthographic", 1);
  511.                         IGGlblViewMode = IG_VIEW_ORTHOGRAPHIC;
  512.                         break;
  513.                     case IG_VIEW_ORTHOGRAPHIC:
  514.                         InteractUpdateMenu("Perspective", 1);
  515.                         IGGlblViewMode = IG_VIEW_PERSPECTIVE;
  516.                         break;
  517.                     }
  518.                     break;
  519.                 case IG_EVENT_DEPTH_CUE:
  520.                     IGGlblDepthCue = !IGGlblDepthCue;
  521.                     InteractUpdateMenu(
  522.                     IGGlblDepthCue ? "Depth Cue" : "No Depth Cue",
  523.                     10);
  524.                     break;
  525.                 default:
  526.                     break;
  527.                 }
  528.  
  529.                 *ChangeFactor = Wx / INTERACT_SUB_WINDOW_WIDTH;
  530.                 return InteractCode;
  531.             }
  532.         }
  533.         else {
  534.             PopUpMenuFunc(0);               /* Pop up the main menu. */
  535.         }
  536.         break;
  537.         case INTR_EVNT_ABORT:
  538.         break;
  539.     }
  540.     }
  541. }
  542.  
  543. /*****************************************************************************
  544. * DESCRIPTION:                                                               *
  545. * Similar to GetGraphicEvent above but for intr_lib get graphic line         *
  546. * routine IGGetGraphicLine, so it may activate the pop up menu async.        *
  547. *                                                                            *
  548. * PARAMETERS:                                                                *
  549. *   x, y:   Location of event.                                               *
  550. *                                                                            *
  551. * RETURN VALUE:                                                              *
  552. *   IntrEventType:  Event type.                                              *
  553. *****************************************************************************/
  554. static IntrEventType LclGetChar(int *x, int *y)
  555. {
  556.     IntrRType Wx, Wy;
  557.     IntrEventType Event;
  558.  
  559.     switch (Event = IntrGetEventWait(x, y)) {
  560.     case INTR_EVNT_SELECT:
  561.         if (!IntrMapEventToRWindow(IGGlblTransWindowID, *x, *y, &Wx, &Wy)) {
  562.         PopUpMenuFunc(0);                   /* Pop up the main menu. */
  563.         }
  564.         break;
  565.     }
  566.  
  567.     return Event;
  568. }
  569.  
  570. /*****************************************************************************
  571. * DESCRIPTION:                                                               M
  572. * Enables or Disables (default) the existance of Input window.             M
  573. * This function should be called BEFORE InitIntrLibWindows above.         M
  574. *                                                                            *
  575. * PARAMETERS:                                                                M
  576. *   HasInputWndw:  Do we want an input window?                               M
  577. *                                                                            *
  578. * RETURN VALUE:                                                              M
  579. *   void                                                                     M
  580. *                                                                            *
  581. * KEYWORDS:                                                                  M
  582. *   GGSetInputWindow                                                         M
  583. *****************************************************************************/
  584. void GGSetInputWindow(IntrBType HasInputWndw)
  585. {
  586.     HasInputWindow = HasInputWndw;
  587. }
  588.  
  589. /*****************************************************************************
  590. * DESCRIPTION:                                                               M
  591. * Test if quit display event occured - SPACE was hit on    keyboard or right    M
  592. * button was clicked on mouse.                             M
  593. *                                                                            *
  594. * PARAMETERS:                                                                M
  595. *   None                                                                     *
  596. *                                                                            *
  597. * RETURN VALUE:                                                              M
  598. *   int:         TRUE, if we need to abort current operation.             M
  599. *                                                                            *
  600. * KEYWORDS:                                                                  M
  601. *   GGIsAbortKeyPressed                                                      M
  602. *****************************************************************************/
  603. int GGIsAbortKeyPressed(void)
  604. {
  605.     int x, y;
  606.  
  607.     return IntrGetEventNoWait(&x, &y) == INTR_EVNT_ABORT;
  608. }
  609.  
  610. /*****************************************************************************
  611. * DESCRIPTION:                                                               *
  612. * Parse the position string and set the BBox location.                 *
  613. *                                                                            *
  614. * PARAMETERS:                                                                *
  615. *   BBox:               Where to save size.                                  *
  616. *   GlblTextWindowPos:  String to parse - "x1, y1, x2, y2"                   *
  617. *                                                                            *
  618. * RETURN VALUE:                                                              *
  619. *   void                                                                     *
  620. *****************************************************************************/
  621. static void SetBBoxSize(IntrBBoxStruct *BBox, char *GlblTextWindowPos)
  622. {
  623.     int i;
  624.     IntrRType XYLoc[4];
  625.  
  626.     if (sscanf(GlblTextWindowPos, "%f, %f, %f, %f",
  627.            &XYLoc[0], &XYLoc[1], &XYLoc[2], &XYLoc[3]) != 4) {
  628.     XYLoc[0] = XYLoc[1] = 0.1;
  629.     XYLoc[2] = XYLoc[3] = 0.9;
  630.     }
  631.  
  632.     for (i = 0; i < 4; i++) {
  633.     if (XYLoc[i] < 0.0)
  634.         XYLoc[i] = 0.0;
  635.     if (XYLoc[i] > 1.0)
  636.         XYLoc[i] = 1.0;
  637.     }
  638.  
  639.     BBox -> Xmin = (int) (XYLoc[0] * GRScreenMaxX);
  640.     BBox -> Ymin = (int) (XYLoc[1] * GRScreenMaxY);
  641.     BBox -> Xmax = (int) (XYLoc[2] * GRScreenMaxX);
  642.     BBox -> Ymax = (int) (XYLoc[3] * GRScreenMaxY);
  643. }
  644.  
  645. /*****************************************************************************
  646. * DESCRIPTION:                                                               *
  647. * Computes the normalized floating bbox for the provided window.         *
  648. *                                                                            *
  649. * PARAMETERS:                                                                *
  650. *   WindowID:    Window to handle.                                           *
  651. *                                                                            *
  652. * RETURN VALUE:                                                              *
  653. *   void                                                                     *
  654. *****************************************************************************/
  655. static void SetViewWindowFBBox(int WindowID)
  656. {
  657.     IntrBBoxStruct *BBox;
  658.     IntrFBBoxStruct FBBox;
  659.     
  660.     /* Compute the aspect ratio of this window and save it so we can match   */
  661.     /* it if the window is resized or zoomed etc.                 */
  662.     BBox = IntrWndwGetBBox(WindowID);
  663.     if (BBox -> _Dy > BBox -> _Dx) {
  664.     /* Normalize the X axis to hold -1 to 1 domain. */
  665.     FBBox.FYmin =                   /* Note the Y axis is flipped. */
  666.          (1.0 / GRScreenAspect) * (((IntrRType) BBox -> _Dy) / BBox -> _Dx);
  667.     FBBox.FYmax = -FBBox.FYmin;
  668.     FBBox.FXmin = -1.0;
  669.     FBBox.FXmax = 1.0;
  670.     }
  671.     else {
  672.     /* Normalize the Y axis to hold -1 to 1 domain. */
  673.     FBBox.FYmin = 1.0;              /* Note the Y axis is flipped. */
  674.         FBBox.FYmax = -1.0;
  675.     FBBox.FXmax =
  676.              GRScreenAspect * (((IntrRType) BBox -> _Dx) / BBox -> _Dy);
  677.     FBBox.FXmin = -FBBox.FXmax;
  678.     }
  679.     IntrWndwSetFBBox(WindowID, &FBBox);
  680. }
  681.  
  682. /*****************************************************************************
  683. * DESCRIPTION:                                                               *
  684. * A call back routine that is invoked whenever the View window needs to be   *
  685. * refreshed.                                     *
  686. *                                                                            *
  687. * PARAMETERS:                                                                *
  688. *   WindowID:    Window to handle.                                           *
  689. *                                                                            *
  690. * RETURN VALUE:                                                              *
  691. *   void                                                                     *
  692. *****************************************************************************/
  693. static void ViewWndwRefreshFunction(int WindowID)
  694. {
  695.     IPObjectStruct *PObj;
  696.     int x1, y1, x2, y2;
  697.  
  698.     IntrWndwClear(WindowID);
  699.     GRGetViewPort(&x1, &y1, &x2, &y2);
  700.     ViewWidth2 = (x2 - x1) / 2;
  701.     ViewHeight2 = (y2 - y1) / 2;
  702.  
  703.     switch (IGGlblViewMode) {         /* Update the current view. */
  704.     case IG_VIEW_ORTHOGRAPHIC:
  705.         GEN_COPY(IGGlblCrntViewMat, IritPrsrViewMat, sizeof(MatrixType));
  706.         break;
  707.     case IG_VIEW_PERSPECTIVE:
  708.         MatMultTwo4by4(IGGlblCrntViewMat, IritPrsrViewMat,
  709.                             IritPrsrPrspMat);
  710.         break;
  711.     }
  712.  
  713.     for (PObj = IGGlblDisplayList; PObj != NULL; PObj = PObj -> Pnext)
  714.     IGDrawObject(PObj);
  715. }
  716.  
  717. /*****************************************************************************
  718. * DESCRIPTION:                                                               *
  719. * A call back routine that is invoked whenever the Trans window needs to be  *
  720. * refreshed.                                     *
  721. *                                                                            *
  722. * PARAMETERS:                                                                *
  723. *   WindowID:    Window to handle.                                           *
  724. *                                                                            *
  725. * RETURN VALUE:                                                              *
  726. *   void                                                                     *
  727. *****************************************************************************/
  728. static void TransWndwRefreshFunction(int WindowID)
  729. {
  730.     switch (IGGlblTransformMode) {
  731.     case IG_TRANS_SCREEN:
  732.         InteractMenu.SubWindows[0].Str = "Screen Coords.";
  733.         break;
  734.     case IG_TRANS_OBJECT:
  735.         InteractMenu.SubWindows[0].Str = "Object Coords.";
  736.         break;
  737.     }
  738.  
  739.     switch (IGGlblViewMode) {
  740.     case IG_VIEW_PERSPECTIVE:
  741.         InteractMenu.SubWindows[1].Str = "Perspective";
  742.         break;
  743.     case IG_VIEW_ORTHOGRAPHIC:
  744.         InteractMenu.SubWindows[1].Str = "Orthographic";
  745.         break;
  746.     }
  747.  
  748.     if (IGGlblDepthCue)
  749.     InteractMenu.SubWindows[10].Str = "Depth Cue";
  750.     else
  751.     InteractMenu.SubWindows[10].Str = "No Depth Cue";
  752.  
  753.     TransWndwRefreshFunctionAux();        /* Draw the transformation menu. */
  754. }
  755.  
  756. /*****************************************************************************
  757. * DESCRIPTION:                                                               *
  758. * Draw the Transformation window, using the InteractiveMenu structure        *
  759. * defined above.                                     *
  760. *  It is assumed that string not inside of SubWindow will be of length 1.    *
  761. *                                                                            *
  762. * PARAMETERS:                                                                *
  763. *   None                                                                     *
  764. *                                                                            *
  765. * RETURN VALUE:                                                              *
  766. *   void                                                                     *
  767. *****************************************************************************/
  768. static void TransWndwRefreshFunctionAux(void)
  769. {
  770.     int i;
  771.  
  772.     GRPushTextSetting();
  773.     GRSetTextJustify(GR_TEXT_HJUSTIFY_CENTER,
  774.              GR_TEXT_VJUSTIFY_CENTER);       /* Draw strings centered. */
  775.  
  776.     GRSetLineStyle(GR_SOLID_LINE, 0, GR_NORM_WIDTH);
  777.  
  778.     for (i = 0; i < INTERACT_NUM_OF_STRINGS; i++) {/* Draw strings of struct.*/
  779.     GRSetColor(InteractMenu.Strings[i].Color);
  780.     IntrWndwRText(InteractMenu.Strings[i].X,
  781.               InteractMenu.Strings[i].Y,
  782.               InteractMenu.Strings[i].Str);
  783.     }
  784.  
  785.     for (i = 0; i < InteractNumOfSubWndws; i++) {
  786.     /* Draw struct sub windows. */
  787.     GRSetColor(InteractMenu.SubWindows[i].Color);
  788.     /* Draw the frame of the SubWindow: */
  789.     IntrWndwRMoveTo(
  790.         InteractMenu.SubWindows[i].X - INTERACT_SUB_WINDOW_WIDTH,
  791.         InteractMenu.SubWindows[i].Y - INTERACT_SUB_WINDOW_HEIGHT);
  792.     IntrWndwRLineTo(
  793.         InteractMenu.SubWindows[i].X + INTERACT_SUB_WINDOW_WIDTH,
  794.         InteractMenu.SubWindows[i].Y - INTERACT_SUB_WINDOW_HEIGHT);
  795.     IntrWndwRLineTo(
  796.         InteractMenu.SubWindows[i].X + INTERACT_SUB_WINDOW_WIDTH,
  797.         InteractMenu.SubWindows[i].Y + INTERACT_SUB_WINDOW_HEIGHT);
  798.     IntrWndwRLineTo(
  799.         InteractMenu.SubWindows[i].X - INTERACT_SUB_WINDOW_WIDTH,
  800.         InteractMenu.SubWindows[i].Y + INTERACT_SUB_WINDOW_HEIGHT);
  801.     IntrWndwRLineTo(
  802.         InteractMenu.SubWindows[i].X - INTERACT_SUB_WINDOW_WIDTH,
  803.         InteractMenu.SubWindows[i].Y - INTERACT_SUB_WINDOW_HEIGHT);
  804.  
  805.     /* Now the strings inside (and if outside, a middle vertical line): */
  806.     if (InteractMenu.SubWindows[i].TextInside)
  807.         IntrWndwRText(InteractMenu.SubWindows[i].X,
  808.               InteractMenu.SubWindows[i].Y,
  809.               InteractMenu.SubWindows[i].Str);
  810.     else {
  811.         IntrWndwRText(InteractMenu.SubWindows[i].X -
  812.                 INTERACT_SUB_WINDOW_WIDTH - 0.1,
  813.               InteractMenu.SubWindows[i].Y,
  814.               InteractMenu.SubWindows[i].Str);
  815.         IntrWndwRLine(InteractMenu.SubWindows[i].X,
  816.               InteractMenu.SubWindows[i].Y -
  817.                 INTERACT_SUB_WINDOW_HEIGHT,
  818.               InteractMenu.SubWindows[i].X,
  819.               InteractMenu.SubWindows[i].Y +
  820.                 INTERACT_SUB_WINDOW_HEIGHT);
  821.     }
  822.     }
  823.  
  824.     GRPopTextSetting();
  825. }
  826.  
  827. /*****************************************************************************
  828. * DESCRIPTION:                                                               *
  829. * Updates entry Entry with a new string Str.                     *
  830. *                                                                            *
  831. * PARAMETERS:                                                                *
  832. *   Str:        New string for entry Entry.                                  *
  833. *   Entry:      Index of entry in menu to modify.                            *
  834. *                                                                            *
  835. * RETURN VALUE:                                                              *
  836. *   void                                                                     *
  837. *****************************************************************************/
  838. static void InteractUpdateMenu(char *Str, int Entry)
  839. {
  840.     GRPushTextSetting();
  841.  
  842.     GRSetTextJustify(GR_TEXT_HJUSTIFY_CENTER,
  843.              GR_TEXT_VJUSTIFY_CENTER);       /* Draw strings centered. */
  844.  
  845.     GRPushViewPort();
  846.     IntrWndwPop(IGGlblTransWindowID, FALSE, FALSE);
  847.  
  848.     GRSetColor(BLACK);                    /* Erase the old string. */
  849.     IntrWndwRText(InteractMenu.SubWindows[Entry].X,
  850.           InteractMenu.SubWindows[Entry].Y,
  851.           InteractMenu.SubWindows[Entry].Str);
  852.  
  853.     InteractMenu.SubWindows[Entry].Str = Str;       /* Update to new one. */
  854.  
  855.     GRSetColor(InteractMenu.SubWindows[Entry].Color);/* And draw the new. */
  856.     IntrWndwRText(InteractMenu.SubWindows[Entry].X,
  857.           InteractMenu.SubWindows[Entry].Y,
  858.           InteractMenu.SubWindows[Entry].Str);
  859.  
  860.     GRPopViewPort();
  861.  
  862.     GRPopTextSetting();
  863. }
  864.  
  865. /*****************************************************************************
  866. * DESCRIPTION:                                                               *
  867. * A call back routine that is invoked whenever the Input window needs to be  *
  868. * refreshed.                                     *
  869. *                                                                            *
  870. * PARAMETERS:                                                                *
  871. *   WindowID:    Window to handle.                                           *
  872. *                                                                            *
  873. * RETURN VALUE:                                                              *
  874. *   void                                                                     *
  875. *****************************************************************************/
  876. static void InputWndwRefreshFunction(int WindowID)
  877. {
  878.     IntrTextWndwRefresh(WindowID);
  879. }
  880.  
  881. /*****************************************************************************
  882. * DESCRIPTION:                                                               *
  883. * Puts a bound on a window size.                                             *
  884. *                                                                            *
  885. * PARAMETERS:                                                                *
  886. *   WindowID:    Window to handle.                                           *
  887. *                                                                            *
  888. * RETURN VALUE:                                                              *
  889. *   void                                                                     *
  890. *****************************************************************************/
  891. static void SetMaximumBBoxSize(int WindowID)
  892. {
  893.    IntrBBoxStruct BBox;
  894.  
  895.    BBox.Xmin = BBox.Ymin = GlblWindowFrameWidth;
  896.    BBox.Xmax = GRScreenMaxX - GlblWindowFrameWidth;
  897.    BBox.Ymax = GRScreenMaxY - GlblWindowFrameWidth;
  898.  
  899.    if (WindowID == IGGlblInputWindowID)
  900.     BBox.Xmin += IntrWndwScrollBarWidth();
  901.  
  902.    IntrWndwSetResizeBBox(&BBox);
  903. }
  904.  
  905. /*****************************************************************************
  906. * DESCRIPTION:                                                               *
  907. * Pops up the pop up menu.                                                   *
  908. *                                                                            *
  909. * PARAMETERS:                                                                *
  910. *   KeyStroke:   Not used.                                                   *
  911. *                                                                            *
  912. * RETURN VALUE:                                                              *
  913. *   void                                                                     *
  914. *****************************************************************************/
  915. static void PopUpMenuFunc(int KeyStroke)
  916. {
  917.     int WindowID;
  918.     IntrIntFunc ViewRefreshFunc;
  919.     IntrBBoxStruct BBox;
  920.  
  921.     if (IntrPopUpMenu(PUWndwMenu, 0)) {
  922.     switch (PUWndwMenu -> SelectedIndex) {
  923.         case 0: /* Redraw all windows. */
  924.         IntrWndwRedrawAll();
  925.         break;
  926.         case 1: /* Move window. */
  927.         if (IntrPopUpActive() == 0 &&
  928.             (WindowID = IntrWndwPick()) > 0)
  929.             IntrWndwMove(WindowID, TRUE);
  930.         break;
  931.         case 2: /* Resize window. */
  932.         if (IntrPopUpActive() == 0 &&
  933.             (WindowID = IntrWndwPick()) > 0) {
  934.             SetMaximumBBoxSize(WindowID);
  935.             if (WindowID == IGGlblViewWindowID) {
  936.             /* DIsable refresh function since we change aspect. */
  937.             ViewRefreshFunc = IntrWndwGetRefreshFunc(IGGlblViewWindowID);
  938.             IntrWndwSetRefreshFunc(IGGlblViewWindowID, NULL);
  939.             }
  940.             IntrWndwResize(WindowID, TRUE);
  941.             if (WindowID == IGGlblViewWindowID) {
  942.             SetViewWindowFBBox(WindowID);
  943.             IntrWndwSetRefreshFunc(IGGlblViewWindowID, ViewRefreshFunc);
  944.             IntrWndwPop(WindowID, TRUE, TRUE);
  945.             }
  946.         }
  947.         break;
  948.         case 3: /* Pop window. */
  949.         if (IntrPopUpActive() == 0 &&
  950.             (WindowID = IntrWndwPick()) > 0)
  951.             IntrWndwPop(WindowID, TRUE, FALSE);
  952.         break;
  953.         case 4: /* Push window. */
  954.         if (IntrPopUpActive() == 0 &&
  955.             (WindowID = IntrWndwPick()) > 0)
  956.             IntrWndwPush(WindowID, TRUE);
  957.         break;
  958.         case 5: /* Zoom window. */
  959.         if (IntrPopUpActive() == 0 &&
  960.             (WindowID = IntrWndwPick()) > 0) {
  961.             SetMaximumBBoxSize(WindowID);
  962.             if (WindowID == IGGlblViewWindowID) {
  963.             /* DIsable refresh function since we change aspect. */
  964.             ViewRefreshFunc = IntrWndwGetRefreshFunc(IGGlblViewWindowID);
  965.             IntrWndwSetRefreshFunc(IGGlblViewWindowID, NULL);
  966.             }
  967.             IntrWndwFullSize(WindowID, TRUE);
  968.             if (WindowID == IGGlblViewWindowID) {
  969.             SetViewWindowFBBox(WindowID);
  970.             IntrWndwSetRefreshFunc(IGGlblViewWindowID, ViewRefreshFunc);
  971.             IntrWndwPop(WindowID, TRUE, TRUE);
  972.             }
  973.         }
  974.         break;
  975.         case 6: /* Reset window sizes. */
  976.         SetBBoxSize(&BBox, GlblViewWndwPos);
  977.         IntrWndwSetBBox(IGGlblViewWindowID, &BBox);
  978.         SetBBoxSize(&BBox, GlblTransWndwPos);
  979.         IntrWndwSetBBox(IGGlblTransWindowID, &BBox);
  980.         if (HasInputWindow) {
  981.             SetBBoxSize(&BBox, GlblInputWndwPos);
  982.             IntrWndwSetBBox(IGGlblInputWindowID, &BBox);
  983.         }
  984.         IntrWndwRedrawAll();
  985.             break;
  986.         case 7: /* Headers. */
  987.         GlblDrawHeader = !GlblDrawHeader;
  988.         IntrWndwSetDrawHeader(IGGlblViewWindowID, GlblDrawHeader);
  989.         IntrWndwSetDrawHeader(IGGlblTransWindowID, GlblDrawHeader);
  990.         if (HasInputWindow)
  991.             IntrWndwSetDrawHeader(IGGlblInputWindowID, GlblDrawHeader);
  992.         IntrWndwRedrawAll();
  993.         break;
  994.     }
  995.     }
  996. }
  997.